#include "LogServer.h"
#include <crtdbg.h>


void LogInitDevNames(const char *basename, TLOGDEVNAMES &names)
{
	if (!basename)
		basename = "Dang";

	int len = (int)strlen(basename) + 1;
	CopyMemory(names.filemapname, basename, len);
	
	*names.mutexnamea = 'a';
	CopyMemory(names.mutexnamea+1, basename, len);

	*names.mutexnameb = 'b';
	CopyMemory(names.mutexnameb+1, basename, len);

	*names.fulleventname = 'c';
	CopyMemory(names.fulleventname+1, basename, len);

	*names.flusheventname = 'd';
	CopyMemory(names.flusheventname+1, basename, len);
}

int WINAPI LogRegisterServer(TLOGSERVERVAR& lsv)
{
	unsigned mapSize = sizeof(TLOGBUFFHEADER) + sizeof(TLOGFUNCTION) * lsv.capacity + 7;

	TLOGDEVNAMES names;
	LogInitDevNames(lsv.mapfilename, names);

	lsv.mapfile = CreateFileMappingA(
		INVALID_HANDLE_VALUE,
		NULL,
		PAGE_READWRITE,
		0, mapSize,
		names.filemapname
		);

	if (!lsv.mapfile || GetLastError() == ERROR_ALREADY_EXISTS)
	{
		CloseHandle(lsv.mapfile);

		return ERROR_ALREADY_EXISTS;
	}
	
	lsv.sharedMemory = (TLOGBUFFHEADER*)MapViewOfFile(
		lsv.mapfile,
		FILE_MAP_WRITE,
		0, 0,
		mapSize
		);

	_ASSERTE(lsv.sharedMemory);

	lsv.sharedMemory->version = LOG_VERSION;
	lsv.sharedMemory->capacity = lsv.capacity;
	lsv.sharedMemory->numRecs = 0;
	lsv.sharedMemory->logchannels.numchannels = 0;

	lsv.startSignal = CreateEventA(NULL, TRUE, FALSE, names.fulleventname);
	lsv.waitSignal = CreateEventA(NULL, TRUE, FALSE, names.flusheventname);
	lsv.mutexA = CreateMutexA(NULL, FALSE, names.mutexnamea);
	lsv.mutexB = CreateMutexA(NULL, FALSE, names.mutexnameb);

	_ASSERTE(lsv.startSignal && lsv.waitSignal && lsv.mutexA && lsv.mutexB);
	
	return ERROR_SUCCESS;
}


void WINAPI FlushQueue(TLOGSERVERVAR& lsv, LOGFN logFnCallback)
{
	DWORD wait;

	wait = WaitForSingleObject(lsv.mutexA, INFINITE);

	if (wait != WAIT_OBJECT_0 && wait != WAIT_ABANDONED)
	{
		_ASSERTE(0);
		ReleaseMutex(lsv.mutexA);

		return;
	}


	// call the callback function
	logFnCallback(lsv);

	lsv.sharedMemory->numRecs = 0;
	
	if (WaitForSingleObject(lsv.startSignal, 0) == WAIT_OBJECT_0)
	{		
		ResetEvent(lsv.startSignal);
		SetEvent(lsv.waitSignal);
	}

	ReleaseMutex(lsv.mutexA);
}


void WINAPI LogUnregisterServer(TLOGSERVERVAR& lsv)
{
	_ASSERTE(lsv.sharedMemory);

	UnmapViewOfFile(lsv.sharedMemory);
	CloseHandle(lsv.mapfile);
	CloseHandle(lsv.startSignal);
	CloseHandle(lsv.waitSignal);
	CloseHandle(lsv.mutexA);
	CloseHandle(lsv.mutexB);
}


/*


  


	SERVER:

	get mutexA

	<flush the queue>

	signal is_empty

	release mutexA





	CLIENT:

	get mutexB
	get mutexA

	if (queue is full)
	{
		flag = 1
		
		signal is_full

		release mutexA

		waiton is_empty

	}


	<write to queue>

	if (flag != 1)
	{
		release mutexA
	}


	release mutexB


  */